using System;

using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Xml;

namespace GDIdotNETgames
{
    public class ClassSprite
    {
        private string _name = string.Empty;
        private Matrix _transform = new Matrix();
        private Size _size = new Size();
        private ClassSpriteImage _image = null;
        private bool _mouseOver = false;
        private bool _mouseOverTopLeft = false;
        private bool _mouseOverTopRight = false;

        public string Name
        {
            get { return _name; }
        }
        public GraphicsPath Path
        {
            get
            {
                GraphicsPath path = new GraphicsPath();
                path.AddRectangle(Rectangle);
                path.Transform(_transform);
                return path;
            }
        }
        public GraphicsPath TopLeftPath
        {
            get
            {
                GraphicsPath path = new GraphicsPath();
                path.AddRectangle(TopLeftRectangle);
                path.Transform(_transform);
                return path;
            }
        }
        public GraphicsPath TopRightPath
        {
            get
            {
                GraphicsPath path = new GraphicsPath();
                path.AddRectangle(TopRightRectangle);
                path.Transform(_transform);
                return path;
            }
        }
        public Matrix Transform
        {
            get { return _transform; }
            set { _transform = value; }
        }
        public float Rotation
        {
            get { return (float)((180d / Math.PI) * Math.Atan2(_transform.Elements[1], _transform.Elements[0])); }
            set { _transform.Rotate(value - Rotation, MatrixOrder.Prepend); }
        }
        public PointF Location
        {
            get { return new PointF(_transform.OffsetX, _transform.OffsetY); }
            set { _transform.Translate(value.X - _transform.OffsetX, value.Y - _transform.OffsetY, MatrixOrder.Append); }
        }
        public PointF TopLeft
        {
            get
            {
                PointF[] topLeft = new PointF[1] { new PointF(0, 0) };
                _transform.TransformPoints(topLeft);
                return topLeft[0];
            }
        }
        public PointF TopRight
        {
            get
            {
                PointF[] topRight = new PointF[1] { new PointF(_size.Width, 0) };
                _transform.TransformPoints(topRight);
                return topRight[0];
            }
        }
        public Rectangle Rectangle
        {
            get { return new Rectangle(new Point(0, 0), _size); }
        }
        public Rectangle TopLeftRectangle
        {
            get { return new Rectangle(new Point(0, 0), new Size(_size.Width / 4, _size.Height / 4)); }
        }
        public Rectangle TopRightRectangle
        {
            get { return new Rectangle(new Point(_size.Width - _size.Width / 4, 0), new Size(_size.Width / 4, _size.Height / 4)); }
        }
        public bool MouseOver
        {
            get { return _mouseOver; }
            set { _mouseOver = value; }
        }
        public bool MouseOverTopLeft
        {
            get { return _mouseOverTopLeft; }
            set { _mouseOverTopLeft = value; }
        }
        public bool MouseOverTopRight
        {
            get { return _mouseOverTopRight; }
            set { _mouseOverTopRight = value; }
        }

        public ClassSprite(XmlReader reader)
        {
            _name = reader.GetAttribute("Name");
            Location = new PointF(
                XmlConvert.ToSingle(reader.GetAttribute("X")),
                XmlConvert.ToSingle(reader.GetAttribute("Y")));
            _size = new Size(
                XmlConvert.ToInt32(reader.GetAttribute("Width")),
                XmlConvert.ToInt32(reader.GetAttribute("Height")));
            Rotation = XmlConvert.ToSingle(reader.GetAttribute("Rotation"));
            XmlReader spriteReader = reader.ReadSubtree();
            while (spriteReader.Read())
                if (spriteReader.IsStartElement("Image"))
                    if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + spriteReader.GetAttribute("Filename")))
                        _image = new ClassSpriteImage(spriteReader);
        }

        public void SerializeToXML(XmlWriter writer)
        {
            writer.WriteStartElement("Sprite");
            writer.WriteAttributeString("Name", _name);
            writer.WriteAttributeString("X", Location.X.ToString());
            writer.WriteAttributeString("Y", Location.Y.ToString());
            writer.WriteAttributeString("Width", _size.Width.ToString());
            writer.WriteAttributeString("Height", _size.Height.ToString());
            writer.WriteAttributeString("Rotation", Rotation.ToString());
            if (_image != null)
                _image.SerializeToXML(writer);
            writer.WriteEndElement();
        }

        public void Update()
        {
            if (_image != null)
                _image.Update();
        }

        public void Draw(Graphics graphics, Matrix worldToScreenTransform)
        {
            worldToScreenTransform.Multiply(_transform, MatrixOrder.Prepend);
            graphics.Transform = worldToScreenTransform;
            if (_image != null)
                graphics.DrawImage(_image.Image, Rectangle, _image.Frame, GraphicsUnit.Pixel);
            if (_mouseOver)
            {
                graphics.DrawRectangle(Pens.Red, Rectangle);
                if (_mouseOverTopLeft)
                    graphics.DrawRectangle(Pens.Blue, TopLeftRectangle);
                else if (_mouseOverTopRight)
                    graphics.DrawRectangle(Pens.Blue, TopRightRectangle);
            }
            else
                graphics.DrawRectangle(Pens.Black, Rectangle);
        }
    }
}
